package com.cyan.note.service.manager.impl;

import com.cyan.note.common.ApiResult;
import com.cyan.note.common.PageResult;
import com.cyan.note.common.ResultCode;
import com.cyan.note.dto.manager.worker.WorkerListDTO;
import com.cyan.note.dto.manager.worker.AvailableWorkerDTO;
import com.cyan.note.dto.manager.worker.WorkerStatsDTO;
import com.cyan.note.entity.Worker;
import com.cyan.note.mapper.WorkerMapper;
import com.cyan.note.service.manager.ManagerWorkerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 店长端-打手管理服务实现类
 * 
 * @author ZhangzhenYu
 * @since 2025-01-15
 */
@Service
@Slf4j
public class ManagerWorkerServiceImpl implements ManagerWorkerService {

    @Autowired
    private WorkerMapper workerMapper;

    @Override
    public ApiResult<PageResult<WorkerListDTO>> getWorkerList(Long shopId, Integer page, Integer size, 
            String keyword, String status, String accountStatus, String level, String skillTags,
            String joinDateStart, String joinDateEnd, String ratingRange, String sortBy, String sortOrder) {
        
        try {
            // 参数转换
            List<String> statusList = StringUtils.hasText(status) ? Arrays.asList(status.split(",")) : null;
            List<String> accountStatusList = StringUtils.hasText(accountStatus) ? Arrays.asList(accountStatus.split(",")) : null;
            List<String> levelList = StringUtils.hasText(level) ? Arrays.asList(level.split(",")) : null;
            List<String> skillTagsList = StringUtils.hasText(skillTags) ? Arrays.asList(skillTags.split(",")) : null;
            
            LocalDateTime joinStart = StringUtils.hasText(joinDateStart) ? 
                    LocalDateTime.parse(joinDateStart, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null;
            LocalDateTime joinEnd = StringUtils.hasText(joinDateEnd) ? 
                    LocalDateTime.parse(joinDateEnd, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null;

            // 计算分页
            int offset = (page - 1) * size;

            // 查询数据
            List<Worker> workers = workerMapper.selectWorkerPage(shopId, keyword, statusList, 
                    accountStatusList, levelList, skillTagsList, joinStart, joinEnd, 
                    ratingRange, sortBy, sortOrder, offset, size);

            // 查询总数
            int total = workerMapper.countWorkers(shopId, keyword, statusList, accountStatusList, 
                    levelList, skillTagsList, joinStart, joinEnd, ratingRange);

            // 转换为DTO
            List<WorkerListDTO> result = new ArrayList<>();
            for (Worker worker : workers) {
                WorkerListDTO dto = new WorkerListDTO();
                dto.setId(worker.getId());
                dto.setWorkerCode(worker.getWorkerCode());
                dto.setNickname(worker.getNickname());
                dto.setRealName(worker.getRealName());
                dto.setPhone(worker.getPhone());
                dto.setGender(worker.getGender());
                dto.setAge(worker.getAge());
                dto.setAvatar(worker.getAvatar());
                dto.setStatus(worker.getStatus());
                dto.setAccountStatus(worker.getAccountStatus());
                dto.setLevel(worker.getLevel());
                dto.setSkillTags(worker.getSkillTags());
                dto.setCommissionRate(worker.getCommissionRate());
                dto.setTotalOrders(worker.getTotalOrders());
                dto.setTotalIncome(worker.getTotalIncome());
                dto.setAverageRating(worker.getAverageRating());
                dto.setLastActiveTime(worker.getLastActiveTime());
                dto.setJoinDate(worker.getJoinDate());
                result.add(dto);
            }

            PageResult<WorkerListDTO> pageResult = PageResult.of(result, total, page, size);
            return ApiResult.success(pageResult);
        } catch (Exception e) {
            log.error("查询打手列表失败", e);
            return ApiResult.error(ResultCode.ERROR, "查询打手列表失败");
        }
    }

    @Override
    public ApiResult<Worker> getWorkerDetail(Long shopId, Long workerId) {
        try {
            Worker worker = workerMapper.selectById(workerId);
            if (worker == null || !worker.getShopId().equals(shopId)) {
                return ApiResult.error(ResultCode.NOT_FOUND, "打手不存在");
            }
            return ApiResult.success(worker);
        } catch (Exception e) {
            log.error("查询打手详情失败", e);
            return ApiResult.error(ResultCode.ERROR, "查询打手详情失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> createWorker(Worker worker, Long operatorId) {
        try {
            // 设置默认值
            worker.setStatus(Worker.Status.OFFLINE);
            worker.setAccountStatus(Worker.AccountStatus.ACTIVE);
            worker.setLevel(Worker.Level.TRAINEE);
            worker.setTotalOrders(0);
            worker.setTotalRatings(0);
            worker.setCreatedAt(LocalDateTime.now());
            worker.setUpdatedAt(LocalDateTime.now());

            int result = workerMapper.insert(worker);
            if (result > 0) {
                return ApiResult.success();
            } else {
                return ApiResult.error(ResultCode.OPERATION_FAILED, "新增打手失败");
            }
        } catch (Exception e) {
            log.error("新增打手失败", e);
            return ApiResult.error(ResultCode.ERROR, "新增打手失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> updateWorker(Worker worker, Long operatorId) {
        try {
            // 检查打手是否存在
            Worker existingWorker = workerMapper.selectById(worker.getId());
            if (existingWorker == null || !existingWorker.getShopId().equals(worker.getShopId())) {
                return ApiResult.error(ResultCode.NOT_FOUND, "打手不存在");
            }

            worker.setUpdatedAt(LocalDateTime.now());
            int result = workerMapper.updateById(worker);
            if (result > 0) {
                return ApiResult.success();
            } else {
                return ApiResult.error(ResultCode.OPERATION_FAILED, "更新打手失败");
            }
        } catch (Exception e) {
            log.error("更新打手失败", e);
            return ApiResult.error(ResultCode.ERROR, "更新打手失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> deleteWorker(Long shopId, Long workerId, Long operatorId) {
        try {
            // 检查打手是否存在
            Worker worker = workerMapper.selectById(workerId);
            if (worker == null || !worker.getShopId().equals(shopId)) {
                return ApiResult.error(ResultCode.NOT_FOUND, "打手不存在");
            }

            int result = workerMapper.deleteById(workerId);
            if (result > 0) {
                return ApiResult.success();
            } else {
                return ApiResult.error(ResultCode.OPERATION_FAILED, "删除打手失败");
            }
        } catch (Exception e) {
            log.error("删除打手失败", e);
            return ApiResult.error(ResultCode.ERROR, "删除打手失败");
        }
    }

    @Override
    public ApiResult<List<AvailableWorkerDTO>> getAvailableWorkers(Long shopId) {
        try {
            List<Worker> workers = workerMapper.selectAvailableWorkers(shopId);
            
            List<AvailableWorkerDTO> result = new ArrayList<>();
            for (Worker worker : workers) {
                AvailableWorkerDTO dto = new AvailableWorkerDTO();
                dto.setId(worker.getId());
                dto.setNickname(worker.getNickname());
                dto.setRealName(worker.getRealName());
                dto.setStatus(worker.getStatus());
                dto.setLevel(worker.getLevel());
                dto.setCommissionRate(worker.getCommissionRate());
                dto.setCurrentOrders(0); // 这里需要通过其他查询获取
                dto.setMaxConcurrentOrders(worker.getMaxConcurrentOrders());
                result.add(dto);
            }

            return ApiResult.success(result);
        } catch (Exception e) {
            log.error("查询可用打手失败", e);
            return ApiResult.error(ResultCode.ERROR, "查询可用打手失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> updateWorkerStatus(Long shopId, Long workerId, String status, Long operatorId) {
        try {
            Worker worker = workerMapper.selectById(workerId);
            if (worker == null || !worker.getShopId().equals(shopId)) {
                return ApiResult.error(ResultCode.NOT_FOUND, "打手不存在");
            }

            worker.setStatus(status);
            worker.setUpdatedAt(LocalDateTime.now());
            
            int result = workerMapper.updateById(worker);
            if (result > 0) {
                return ApiResult.success();
            } else {
                return ApiResult.error(ResultCode.OPERATION_FAILED, "更新打手状态失败");
            }
        } catch (Exception e) {
            log.error("更新打手状态失败", e);
            return ApiResult.error(ResultCode.ERROR, "更新打手状态失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> updateWorkerAccountStatus(Long shopId, Long workerId, String accountStatus, Long operatorId) {
        try {
            Worker worker = workerMapper.selectById(workerId);
            if (worker == null || !worker.getShopId().equals(shopId)) {
                return ApiResult.error(ResultCode.NOT_FOUND, "打手不存在");
            }

            worker.setAccountStatus(accountStatus);
            worker.setUpdatedAt(LocalDateTime.now());
            
            int result = workerMapper.updateById(worker);
            if (result > 0) {
                return ApiResult.success();
            } else {
                return ApiResult.error(ResultCode.OPERATION_FAILED, "更新打手账户状态失败");
            }
        } catch (Exception e) {
            log.error("更新打手账户状态失败", e);
            return ApiResult.error(ResultCode.ERROR, "更新打手账户状态失败");
        }
    }

    @Override
    public ApiResult<WorkerStatsDTO> getWorkerStats(Long shopId) {
        try {
            WorkerStatsDTO stats = new WorkerStatsDTO();
            
            // 获取打手状态概览
            WorkerMapper.WorkerStatusOverview statusOverview = workerMapper.selectWorkerStatusOverview(shopId);
            
            // 基本统计
            stats.setTotalWorkers(statusOverview != null && statusOverview.getTotal() != null ? statusOverview.getTotal() : 0);
            stats.setIdleWorkers(statusOverview != null && statusOverview.getIdle() != null ? statusOverview.getIdle() : 0);
            stats.setWorkingWorkers(statusOverview != null && statusOverview.getWorking() != null ? statusOverview.getWorking() : 0);
            stats.setOnlineWorkers(stats.getIdleWorkers() + stats.getWorkingWorkers() + 
                (statusOverview != null && statusOverview.getRest() != null ? statusOverview.getRest() : 0));
            stats.setOfflineWorkers(statusOverview != null && statusOverview.getOffline() != null ? statusOverview.getOffline() : 0);
            
            // 计算在线率
            if (stats.getTotalWorkers() > 0) {
                BigDecimal onlineRate = BigDecimal.valueOf(stats.getOnlineWorkers())
                        .divide(BigDecimal.valueOf(stats.getTotalWorkers()), 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100));
                stats.setOnlineRate(onlineRate);
            } else {
                stats.setOnlineRate(BigDecimal.ZERO);
            }
            
            // 模拟其他统计数据（实际项目中需要从数据库查询）
            stats.setAverageRating(BigDecimal.valueOf(4.2));
            stats.setTodayActiveWorkers(stats.getOnlineWorkers());
            stats.setMonthlyNewWorkers(2);
            
            // 等级分布
            List<WorkerStatsDTO.WorkerLevelStats> levelDistribution = new ArrayList<>();
            WorkerStatsDTO.WorkerLevelStats goldLevel = new WorkerStatsDTO.WorkerLevelStats();
            goldLevel.setLevel("gold");
            goldLevel.setLevelName("黄金");
            goldLevel.setCount(stats.getTotalWorkers() > 0 ? stats.getTotalWorkers() / 2 : 0);
            goldLevel.setPercentage(stats.getTotalWorkers() > 0 ? BigDecimal.valueOf(50) : BigDecimal.ZERO);
            levelDistribution.add(goldLevel);
            
            WorkerStatsDTO.WorkerLevelStats silverLevel = new WorkerStatsDTO.WorkerLevelStats();
            silverLevel.setLevel("silver");
            silverLevel.setLevelName("白银");
            silverLevel.setCount(stats.getTotalWorkers() > 0 ? stats.getTotalWorkers() / 3 : 0);
            silverLevel.setPercentage(stats.getTotalWorkers() > 0 ? BigDecimal.valueOf(33) : BigDecimal.ZERO);
            levelDistribution.add(silverLevel);
            
            stats.setLevelDistribution(levelDistribution);
            
            // 状态分布
            List<WorkerStatsDTO.WorkerStatusStats> statusDistribution = new ArrayList<>();
            
            WorkerStatsDTO.WorkerStatusStats idleStatus = new WorkerStatsDTO.WorkerStatusStats();
            idleStatus.setStatus("idle");
            idleStatus.setStatusName("空闲");
            idleStatus.setCount(stats.getIdleWorkers());
            idleStatus.setPercentage(stats.getTotalWorkers() > 0 ? 
                BigDecimal.valueOf(stats.getIdleWorkers()).divide(BigDecimal.valueOf(stats.getTotalWorkers()), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : 
                BigDecimal.ZERO);
            statusDistribution.add(idleStatus);
            
            WorkerStatsDTO.WorkerStatusStats workingStatus = new WorkerStatsDTO.WorkerStatusStats();
            workingStatus.setStatus("working");
            workingStatus.setStatusName("工作中");
            workingStatus.setCount(stats.getWorkingWorkers());
            workingStatus.setPercentage(stats.getTotalWorkers() > 0 ? 
                BigDecimal.valueOf(stats.getWorkingWorkers()).divide(BigDecimal.valueOf(stats.getTotalWorkers()), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : 
                BigDecimal.ZERO);
            statusDistribution.add(workingStatus);
            
            stats.setStatusDistribution(statusDistribution);
            
            // 优秀打手列表（空列表，实际需要查询数据库）
            stats.setTopWorkers(new ArrayList<>());
            
            return ApiResult.success(stats);
        } catch (Exception e) {
            log.error("获取打手统计数据失败", e);
            return ApiResult.error(ResultCode.ERROR, "获取打手统计数据失败");
        }
    }
}